﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Data;
using System.Xml.Serialization;
using System.IO;

using EntityMap.Meta;
using System.Data.SqlClient;
using System.Reflection;
using System.Collections;

namespace EntityMap
{
    public partial class EntityManager
    {
        private string _connectionString = null;
        private string _mapsFolder = null;

        private Hashtable _maps;

        /// <summary>
        /// The root folder for maps files.
        /// </summary>
        /// <remarks>
        /// If not specified the map folder is current application execution.
        /// </remarks>
        public string MapsFolder
        {
            get
            {
                return _mapsFolder;
            }
            set
            {
                _mapsFolder = value;
            }
        }

        /// <summary>
        /// A database connection string 
        /// </summary>
        public string ConnectionString
        {
            get
            {
                return _connectionString;
            }
            set
            {
                _connectionString = value;
            }
        }

        public EntityManager()
        {
            _maps = new Hashtable();
        }

        public EntityManager( string connectionString ) 
            : this()
        {
            _connectionString = connectionString;
        }

        public EntityManager( string connectionString, string mapsFolder )
            : this( connectionString )
        {
            _mapsFolder = mapsFolder;
        }

        protected EntityInfo GetEntityInfo( Type entityType )
        {
            // check cache
            if( _maps.ContainsKey( entityType.Name ) )
            {
                return _maps[entityType.Name] as EntityInfo;
            }

            EntityInfo einfo = null;

            XmlSerializer serializer = new XmlSerializer( typeof( EntityInfo ) );

            string fileName = String.Empty;

            if( !String.IsNullOrEmpty( _mapsFolder ) )
            {
                fileName = String.Format( @"{0}\{1}.xml", _mapsFolder, entityType.Name );
            }
            else
	        {
                fileName = String.Format( "{0}.xml", entityType.Name );
	        }

            if( !File.Exists( fileName ) )
            {
                throw new EntityMapException( String.Format( "The {0} file is not exist!", fileName ) );
            }

            using( FileStream fs = new FileStream( fileName, FileMode.Open, FileAccess.Read, FileShare.Read ) )
            {
                einfo = serializer.Deserialize( fs ) as EntityInfo;
            }

            // add metadata to cache
            _maps.Add( entityType.Name, einfo );

            return einfo;
        }

        public void SaveEntityInfo( Type entityType, EntityInfo entityInfo )
        {
            XmlSerializer serializer = new XmlSerializer( typeof( EntityInfo ) );

            string fileName = String.Empty;

            if( !String.IsNullOrEmpty( fileName ) )
            {
                fileName = String.Format( @"{0}\{1}.xml", _mapsFolder, entityType.Name );
            }
            else
            {
                fileName = String.Format( "{0}.xml", entityType.Name );
            }

            using( FileStream fs = new FileStream( fileName, FileMode.Create, FileAccess.Write ) )
            {
                serializer.Serialize( fs, entityInfo );
            }
        }
    }
}
